package com.jungle.bfi.service.metadata.impl;

import com.jungle.base.dao.SpecBuilder;
import com.jungle.base.domain.bo.BaseUserBo;
import com.jungle.base.service.AbstractService;
import com.jungle.bfi.domain.bo.ApiMetadataBo;
import com.jungle.bfi.domain.qo.ApiMetadataQo;
import com.jungle.bfi.entity.ApiMetadataPo;
import com.jungle.bfi.service.metadata.ApiMetadataService;
import org.n3r.idworker.Sid;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class ApiMetadataServiceImpl extends AbstractService<ApiMetadataPo, ApiMetadataBo, String> implements ApiMetadataService {
    @Override
    protected String getBoId(ApiMetadataBo bo) {
        if (bo.getId() == null) {
            Specification<ApiMetadataPo> spec = new SpecBuilder<ApiMetadataPo>(bo).toSpec();
            List<ApiMetadataPo> list = this.findAll(spec);
            if (!list.isEmpty()) {
                String oldId = list.get(0).getId();
                bo.setId(oldId);
            }
        }
        return bo.getId();
    }

    @Override
    protected String newPoId() {
        return Sid.nextShort();
    }

    @Override
    protected ApiMetadataPo createPo(ApiMetadataBo bo, BaseUserBo userBo) {
        return mapper.map(bo, ApiMetadataPo.class);
    }

    /**
     * 查询所有包含子节点
     *
     * @param qo 查询条件
     */
    @Override
    public List<ApiMetadataPo> findAllWithChild(ApiMetadataQo qo) {
        List<ApiMetadataPo> result = new ArrayList<>();
        Specification<ApiMetadataPo> spec = new SpecBuilder<ApiMetadataPo>(qo).toSpec();
        List<ApiMetadataPo> list = this.findAll(spec);
        if (list.isEmpty()) {
            return result;
        }
        list.forEach(po -> findChild(po, result));

        return result;
    }

    /**
     * 混合类型数据（不是简单数据类型）
     */
    private static final List<String> MIX_TYPE_LIST = Arrays.asList("object", "array", "ref");

    public void findChild(ApiMetadataPo po, List<ApiMetadataPo> result) {
        result.add(po);
        // 若当前对象不是简单类型，就递归
        if (MIX_TYPE_LIST.contains(po.getOriginType())) {
            Specification<ApiMetadataPo> spec = po.toChildSpec();
            List<ApiMetadataPo> list = this.findAll(spec);
            list.forEach(po1 -> findChild(po1, result));
        }
    }
}
